//*********************************************************
//
//    Copyright (c) Microsoft. All rights reserved.
//    This code is licensed under the Apache License, Version 2.0.
//    THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
//    ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
//    IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
//    PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
//
//*********************************************************

namespace Microsoft.Research.eResearch.Common.Threading
{
    using System;
    using System.Threading;

    /// <summary>
    /// Provides static methods for easily accessing the ThreadPool using anonymous methods.
    /// </summary>
    public static class ThreadPoolHelper
    {
        /// <summary>
        /// Queues a method for execution. The method executes when a thread pool thread becomes available.
        /// </summary>
        /// <param name="callback">The callback to execute on a new thread pool thread.</param>
        /// <returns><c>true</c> if the method is successfully queued.</returns>
        /// <exception cref="System.OutOfMemoryException"/>
        public static bool QueueUserWorkItem(Action callback)
        {
            return ThreadPool.QueueUserWorkItem((s) => callback());
        } 

        /// <summary>
        /// Queues a method for execution. The method executes when a thread pool thread becomes available.
        /// </summary>
        /// <typeparam name="T">The type of the first parameter passed to the method.</typeparam>
        /// <param name="state">The first parameter.</param>
        /// <param name="callback">The callback to execute on a new thread pool thread.</param>
        /// <returns><c>true</c> if the method is successfully queued.</returns>
        public static bool QueueUserWorkItem<T>(T state, Action<T> callback)
        {
            return ThreadPool.QueueUserWorkItem(s => callback(state), null);
        } 

        /// <summary>
        /// Queues a method for execution. The method executes when a thread pool thread becomes available.
        /// </summary>
        /// <typeparam name="TType1">The type of the first parameter passed to the method.</typeparam>
        /// <typeparam name="TType2">The type of the second parameter passed to the method.</typeparam>
        /// <param name="state1">The first parameter.</param>
        /// <param name="state2">The second parameter.</param>
        /// <param name="callback">The callback to execute on a new thread pool thread.</param>
        /// <returns><c>true</c> if the method is successfully queued.</returns>
        public static bool QueueUserWorkItem<TType1, TType2>(TType1 state1, TType2 state2, Action<TType1, TType2> callback)
        {
            return ThreadPool.QueueUserWorkItem(s => callback(state1, state2), null);
        } 

        /// <summary>
        /// Queues a method for execution. The method executes when a thread pool thread becomes available.
        /// </summary>
        /// <typeparam name="TType1">The type of the first parameter passed to the method.</typeparam>
        /// <typeparam name="TType2">The type of the second parameter passed to the method.</typeparam>
        /// <typeparam name="TType3">The type of the third parameter passed to the method.</typeparam>
        /// <param name="state1">The first parameter.</param>
        /// <param name="state2">The second parameter.</param>
        /// <param name="state3">The third parameter.</param>
        /// <param name="callback">The callback to execute on a new thread pool thread.</param>
        /// <returns><c>true</c> if the method is successfully queued.</returns>
        public static bool QueueUserWorkItem<TType1, TType2, TType3>(TType1 state1, TType2 state2, TType3 state3, Action<TType1, TType2, TType3> callback)
        {
            return ThreadPool.QueueUserWorkItem(s => callback(state1, state2, state3), null);
        } 

        /// <summary>
        /// Queues a method for execution. The method executes when a thread pool thread becomes available.
        /// </summary>
        /// <typeparam name="TType1">The type of the first parameter passed to the method.</typeparam>
        /// <typeparam name="TType2">The type of the second parameter passed to the method.</typeparam>
        /// <typeparam name="TType3">The type of the third parameter passed to the method.</typeparam>
        /// <typeparam name="TType4">The type of the fourth parameter passed to the method.</typeparam>
        /// <param name="state1">The first parameter.</param>
        /// <param name="state2">The second parameter.</param>
        /// <param name="state3">The third parameter.</param>
        /// <param name="state4">The fourth parameter.</param>
        /// <param name="callback">The callback to execute on a new thread pool thread.</param>
        /// <returns><c>true</c> if the method is successfully queued.</returns>
        public static bool QueueUserWorkItem<TType1, TType2, TType3, TType4>(TType1 state1, TType2 state2, TType3 state3, TType4 state4, Action<TType1, TType2, TType3, TType4> callback)
        {
            return ThreadPool.QueueUserWorkItem(s => callback(state1, state2, state3, state4), null);
        } 
    }
}
